#include "ZxPokerRange.h"
#include <QPainter>
#include <QPaintEvent>
#include <QDebug>
#include <QPushButton>
#include <QIcon>
#include <QImage>

ZxPokerRange::ZxPokerRange(QWidget *parent)
    : QDialog(parent)
{
    ui.setupUi(this);

    m_sel = 0;
    m_mousepressed = false;
    m_mousemove = false;

    this->resize(580, 520);
    this->setMouseTracking(true);

    QPushButton* btnclear = new QPushButton(this);
    btnclear->move(this->rect().width() - btnclear->width(), 2);
    btnclear->setText("clear");

    connect(btnclear, &QPushButton::clicked, this, &ZxPokerRange::OnClearCardSelection);
    
    QIcon icon(":/ZxPokerRange/logo.png");
    
    this->setWindowIcon(icon);
}

void ZxPokerRange::paintEvent(QPaintEvent* pe)
{
    
    static char cards[] = {
        'A','K','Q','J','T','9','8','7','6','5','4','3','2','1'
    };
    int ncards = 13;


    QDialog::paintEvent(pe);
    QPainter p(this);
    p.fillRect(m_cards, Qt::white);

    this->CalculateGrids();
    int top = m_yaxis.front();
    int bottom = m_yaxis.last();

    p.setPen(Qt::lightGray);
    for (auto x : m_xaxis) {

        //qDebug() << "vl=>" << x << "t=" << top << "b=" << bottom;
        p.drawLine(x, top, x, bottom);
    }

    int left = m_xaxis.front();
    int right = m_xaxis.last();
    for (auto y : m_yaxis) {
        p.drawLine(left, y,right, y);
    }

    QFontMetrics fm = p.fontMetrics();
    int length = fm.width("AKs");
    
    int tmargin = (m_cardsz.width() - length) / 2;

    int cnt = m_xaxis.size();
    QString text;
   
    for (int x = 0; x < cnt-1;x++) {
        for (int y = 0; y < cnt-1;y++) {
            int px = m_xaxis[x];
            int py = m_yaxis[y];

            QPoint gridindex(x, y);
            QRect  rect(px, py, m_cardsz.width(), m_cardsz.height());
            rect.adjust(1, 1, -1, -1);
            
            if (x >= y) {
                p.fillRect(rect, Qt::lightGray);
                p.setPen(Qt::black);
            }
                      
            
            if (m_selected.indexOf(gridindex) >= 0) {
                p.fillRect(rect, Qt::red);
                p.setPen(Qt::white);
            }
            else if(x <y){
                p.fillRect(rect, Qt::white);
                p.setPen(Qt::black);
            }




            if (x == y) {
                text = QString("%1%2").arg(cards[x]).arg(cards[x]);
                p.drawText(px+ tmargin,py+m_cardsz.height()/2, text);
            }
            else if (x > y) {
                text = QString("%1%2s").arg(cards[y]).arg(cards[x]);
                p.drawText(px+ tmargin, py + m_cardsz.height() / 2, text);
            }
            else {
                text = QString("%1%2o").arg(cards[x]).arg(cards[y]);
                p.drawText(px+ tmargin, py + m_cardsz.height() / 2, text);
            }
        }
    }
    p.setPen(Qt::black);
    text = QString("selection: %1 hands,%2%").arg(m_sel).arg(QString::number(m_sel * 100.0 / 1362,'f',2));
    p.drawText(this->rect().width() / 2-60, 15, text);
}

void ZxPokerRange::resizeEvent(QResizeEvent* r)
{
    //this->CalculateGrids();
    QDialog::resizeEvent(r);
}

void ZxPokerRange::mouseReleaseEvent(QMouseEvent* m)
{

    if (!m_mousepressed || !m_mousemove) {
        this->SingleSelection(m->pos());
        QDialog::mouseReleaseEvent(m);
        return;
    }

    m_mousepressed = false;
    m_mousemove = false;

    QRect r = QRect(m_dragstart, m_dragend).normalized();

    //qDebug() << "drag-rect==>" << r;
    int n = m_xaxis.size();

    int left = -1, right = -1, top = -1, bottom = -1;

    for (int i = 0; i < n - 1; i++) {
        float x = m_xaxis[i];
        if (r.left() <= x + m_cardsz.width() && left < 0) {
            left = i;
        }
        if (r.right() <= x + m_cardsz.width() && right < 0) {
            right = i;
        }
    }

    for (int i = 0; i < n - 1; i++) {
        float y = m_yaxis[i];
        if (r.top() <= y + m_cardsz.height() && top < 0) {
            top = i;
        }
        if (r.bottom() <= y + m_cardsz.height() && bottom < 0) {
            bottom = i;
        }
    }

    for (int i = left; i <= right; i++) {
        for (int j = top; j <= bottom; j++) {
            QPoint p(i, j);
            if (m_selected.indexOf(p) >= 0) {
                m_selected.removeOne(p);
            }
            else {
                m_selected.push_back(p);
            }
        }
    }
    qDebug() << "selecton==>" << m_selected;
    qDebug() << "left=" << left << ",right=" << right << ",top=" << top << ",bottom" << bottom;

    this->TotalHands();

    this->update();
    QDialog::mouseReleaseEvent(m);
}

void ZxPokerRange::mousePressEvent(QMouseEvent* m)
{
    m_mousepressed = true;
    m_dragstart = m->pos();


    QDialog::mousePressEvent(m);
}

void ZxPokerRange::mouseMoveEvent(QMouseEvent* m)
{
    if (!m_mousepressed) {
        QDialog::mouseMoveEvent(m);
        return;
    }

    int mousemove = (m->pos() - m_dragstart).manhattanLength();
    if (mousemove < QApplication::startDragDistance()) {
        m_mousemove = false;
        return;
    }

    m_mousemove = true;
    m_dragend = m->pos();
    QDialog::mouseMoveEvent(m);
}

void ZxPokerRange::CalculateGrids()
{
    int margin = 10;

    this->m_xaxis.clear();
    this->m_yaxis.clear();

    m_cards = this->rect().adjusted(margin, 30, -margin, -margin);

    float dx = m_cards.width()*1.0 / 13;
    float dy = m_cards.height()*1.0 / 13;

    m_cardsz.setWidth(dx);
    m_cardsz.setHeight(dy);

    int tmp = m_cards.left();
    while (m_xaxis.size() < 14) {
        m_xaxis << tmp;
        tmp += dx;
    }

    tmp = m_cards.top();
    while (m_yaxis.size() < 14) {
        m_yaxis << tmp;
        tmp += dy;
    }

   // qDebug() << "x:" << m_xaxis << "y:" << m_yaxis;

}

void ZxPokerRange::TotalHands()
{
    m_sel = 0;
    for (auto& sel : m_selected) {
        if (sel.x() == sel.y()) {
            m_sel += 6;
        }
        else if (sel.x() > sel.y()) {
            m_sel += 4;
        }
        else {
            m_sel += 12;
        }
    }
}

void ZxPokerRange::SingleSelection(QPoint p)
{
    auto pos = p;
    int n = m_xaxis.size();

    int i = 0;
    int j = 0;
    for (; i < n - 1; i++) {
        for (j = 0; j < n - 1; j++) {
            if (pos.x() >= m_xaxis[i] && pos.x() <= m_xaxis[i + 1]
                && pos.y() >= m_yaxis[j] && pos.y() <= m_yaxis[j + 1]) {
                goto lbl_find;
            }
        }
    }

lbl_find:
    if (i < n - 1 && j < n - 1) {
        QPoint p(i, j);
        if (m_selected.indexOf(p) >= 0) {
            m_selected.removeOne(p);
        }
        else {
            m_selected.push_back(p);
        }
    }

    this->TotalHands();

    this->update();

}

void ZxPokerRange::OnClearCardSelection()
{
    this->m_selected.clear();
    this->update();
}